#!/usr/bin/env python
# -*- coding:utf-8 -*-
'''
# -------------------------------------------------------------------------------
# Purpose:    解析zabbix聚合报告，获取链接地址
#
# Author:      yewei8
#
# Created:     2020-03-13
#
# Copyright:   (c) Hikvision.com 2020
# -------------------------------------------------------------------------------
'''
import os
import re
import json
import logging
import requests
import asyncio
import aiohttp
import numpy as np
import pandas as pd
from pathlib import Path
from copy import deepcopy
from performance.utils import utils
from performance.py_chart import ItemAssign
from performance.utils.ExcelLibrary import ExcelLibrary

ZABBIX_LINK = "http://stt.hiktest.com/zabbix/php"

logger = logging.getLogger(__name__)


class ZabbixHostMonitor():
    """
    解析Zabbix 主机监控信息
    """
    def __init__(self):
        self.result_data = []
        self.token = ""
        self.items = {}
        self.files_path = []
        self.excel = ExcelLibrary()

    def _get_token(self, username:str, password:str):
        """
        登录zabbix，获取token
            :param username:用户名
            :param password:登录密码
        :return:
        """
        res = requests.post(f"{ZABBIX_LINK}/api_jsonrpc.php", json={"jsonrpc":"2.0",
                                                                    "method":"user.login",
                                                                    "id": 1,
                                                                    "auth": None,
                                                                    "params":{"user":username,
                                                                              "password":password}
                                                                    })

        self.token = res.json().get("result", "")

    @property
    def result(self) -> list:
        return self.result_data

    def set_failed_result(self, result:dict, msg:str):
        """
        设置执行失败的结果
            :param result: 结果对象
            :param msg: 失败的信息
        :return:
        """
        result['msg'] = msg
        result['success'] = False

    def get_zabbix_response(self, method:str, params:dict):
        """
        获取zabbix请求的响应结果
            :param method: 请求方法
            :param params: 请求参数
        :return:
        """
        try:
            res = requests.post(f"{ZABBIX_LINK}/api_jsonrpc.php",
                                json={
                                    "jsonrpc": "2.0",
                                    "method": method,
                                    "auth": self.token,
                                    "id":1,
                                    "params": params
                                })
            result = res.json().get("result", [])
        except Exception as error:
            logger.error(f"获取zabbix请求的响应结果：{error}")
            raise Exception(error)
        return result

    def get_monitor_data(self, username:str, password:str, time_range:list,
                         data:list=None, width:int=960, theme_name:str="DARK"):
        """
        获取Zabbix监控数据项线下
            :param username:用户名
            :param password:登录密码
            :param time_range:监控时间范围
            :param data:监控查找对象信息
            :param width:生成的图片宽度
            :param theme_name:生成的图片配色主题
        :return:
        """
        self._get_token(username, password)
        start_time = time_range[0] if len(time_range) > 0 else ""
        end_time = time_range[1] if len(time_range) > 1 else ""
        for one in data:
            single = deepcopy(one)
            host_id = single.get("id", "")
            grounp_id = single.get("grounpid", "")
            template_id = single.get("templateid", "")
            single.update({"success":True, "msg":"", "data":[]})
            self.result_data.append(single)
            if not (start_time and end_time):
                self.set_failed_result(single, "请传入参数 start_time（起始时间）, end_time（终止时间）")
                continue

            paramters = {"output": "extend", "sortfield": "name"}
            if template_id:
                paramters.update({"templateids":template_id})
            elif host_id:
                paramters.update({"hostids":host_id})
            elif grounp_id:
                paramters.update({"groupids": grounp_id})
            else:
                self.set_failed_result(single, "请传入参数 template_id或host_id或grounp_id")
                continue

            try:
                results = self.get_zabbix_response("item.get", paramters)
            except Exception as error:
                self.set_failed_result(single,  f"{error}")
                continue

            history_data = {}
            self.items = {x["itemid"]:x["name"] for x in results}
            for item in results:
                item_id = item["itemid"]
                params = {"output": "extend", "itemids": item_id, "history": 0}
                time_from = utils.date_string_2_int(start_time)
                time_till = utils.date_string_2_int(end_time)
                single.update({
                    "start_time":utils.date_float_2_string(time_from),
                    "end_time": utils.date_float_2_string(time_till),
                })
                params.update(
                    {
                        "time_from": time_from,
                        "time_till": time_till,
                    }
                )
                try:
                    history = self.get_zabbix_response("history.get", params)
                except Exception as error:
                    logger.error(f"获取{item}的监控历史数据错误：{error}")
                    continue
                item_data = { utils.date_float_2_string(x.get("clock", 0)):float(x.get("value", "")) for x in history }
                history_data.update({ item_id:item_data })
            self.generate_data(history_data, single, width,  theme_name)


    def generate_data(self, history:dict, result:dict, width:int=960,  theme_name:str="DARK"):
        """
        生成监听数据
            :param history:监听数据
            :param result:结果对象
            :param width:生成的图片宽度
            :param theme_name:生成的图片配色主题
        :return:
        """
        df = pd.DataFrame.from_dict(history, orient="index")
        df = df.where(df.notnull(), None)
        result.setdefault("data", [])
        col_mean = df.mean(1)
        col_max = df.max(1)
        col_min = df.min(1)
        # statistics = {
        #     "min": col_min,
        #     "mean": col_mean,
        #     "max": col_max
        # }
        # statistics_df = pd.DataFrame.from_dict(statistics)

        height = int(width*9/16)
        time_data = df.columns.values
        echart = ItemAssign(width=f'{width}px', height=f'{height}px', theme_name=theme_name)
        echart.set_x_xis(time_data)
        for item_id in history.keys():
            values = df.loc[item_id].values
            item_name = self.items.get(item_id, "")
            echart.set_y_xis(item_name, values)
            result["data"].append({
                "item_id":item_id,
                "item_name": item_name,
                "max": col_max[item_id],
                "mean": col_mean[item_id],
                "min": col_min[item_id],
            })
        title = f"{result.get('name', '')} - {result.get('templatename', '')}"
        echart.set_global_options(title=title,
                                  subtitle=f"{result.get('start_time', '')} ~ {result.get('end_time', '')}")
        files = echart.save(title)
        html_file = files.get("html_path", "")
        picture_path = files.get("picture_path", "")
        if html_file:
            self.files_path.append(html_file)
            result.update({"html_file":html_file})
        if picture_path:
            self.files_path.append(picture_path)
            result.update({"picture_path":picture_path})

    def delete_picture(self):
        """删除生成文件"""
        for path in self.files_path:
            try:
                os.remove(path)
            except Exception as error:
                logger.error(f"删除文件错误：{error}")


if __name__ == '__main__':
    html = ZabbixHostMonitor()
    para_data = [{
        "host_id":"11042",
        "template_id":"11022",
    }]
    id_links = html.get_monitor_data("Admin", "zabbix", ["2020-03-03T10:10:06.000Z", "2020-03-28T10:12:06.000Z"], para_data)
    for res in html.result:
        if res.get("success", False):
            print(res.get("data", []))
    html.delete_picture()

